--lua面向对象

--封装
--面向对象这些都是由表衍生出来的
object={}
object.id=1

function object:Test()
	print(self.id)
end

--:就是把object作为第一个参数传入
function object:new()
	local obj={}
	--结合元表的__index
	setmetatable(obj,self)
	self.__index=self

	return obj
	--返回的是一张表
end

local myobj=object:new()
print(myobj)
print(myobj.id)
myobj:Test()

--不会修改，相当于直接加一个新的属性
myobj.id=2
print(object.id)
print(myobj.id)
--传入的额是myobj作为第一个对象，所以打印的是mobj的id
myobj:Test()

--继承
--写一个用于继承的方法
function object:subclass(className)
	--利用_G表将一个string变为一个table
	_G[className]={}

	local obj=_G[className]
	self.__index=self

	--定义一个super
	obj.super=self
	setmetatable(obj,self)
end

object:subclass("Person")
print(Person)
print(Person.id)

local p1=Person:new()
--通过链式逐层往上找到id
print(p1.id)

object:subclass("Monster")

local Mon1=Monster:new()
print(Mon1.id)

--多态
--相同行为不同表现
object:subclass("GameObject")
GameObject.posX=0;
GameObject.posY=0;
function GameObject:Move()
	self.posX=self.posX+1
	self.posY=self.posY+1
	print("位置X "..self.posX)
	print("位置Y "..self.posY)
end
GameObject:subclass("Player")
function Player:Move()
	--super.Move()
	--这种方式调用相当于把基类表作为第一个参数传入
	--这样不同对象修改的永远是基类而不是对象自己的
	--应该避免这种,所以手动传入第一个参数
	--self.super:Move(),这种方式是错误的
	self.super.Move(self)
end

local p1=Player:new()
p1:Move()

--不同对象使用的成员变量居然相同
--修改后解决
local p2=Player:new()
p2:Move()